
require('./modules').urls(require, exports, environment);

/*** keyLeave
*/
exports.keyLeaves = [
    'protocol', 'user', 'password', 'domains', 'port', 'root', 'directory',
    'file', 'query', 'anchor'
];

/*** looseExpression
*/
exports.looseExpression = new RegExp( /* url */
    "^" +
    "(?:" +
        "(?![^:@]+:[^:@/]*@)" + /* negative lookahead */
        "([^:/?#.]+)" + /* protocol */
        ":" +
    ")?" +
    "(?://)?" +
    "(" + /* authority */
        "(?:" +
            "(" + /* userInfo */
                "([^:@]*)" + /* user */
                ":?"
                + "([^:@]*)" + /* password */
            ")?" +
            "@" +
        ")?" +
        "([^:/?#]*)" + /* domain */
        "(?::(\\d*))?" + /* port */
    ")" +
    "(?:" +
        "(" + /* path */
            "(?:" +
                "(/)" + /* root */
                "(?:" +
                    "[^?#]" + /* directory */
                    "(?![^?#/]*\\.[^?#/.]+(?:[?#]|$))" +
                        /* negative lookahead */
                ")*" +
                "/?" +
            ")?" +
            "([^?#/]*)" + /* file */
        ")" +
        "(?:\\?([^#]*))?" + /* query */
        "(?:#(.*))?" + /* anchor */
    ")"
);

/*** parseLooseUrl
*/
exports.parseLooseUrl = Parser(looseExpression);
/*todo remove this bit of uncertainty about the existence of encodeURIComponent */
var encodeComponent;
if (window.encodeURIComponent) {
    encodeComponent = window.encodeURIComponent;
} else {
    warn("encodeURIComponent does not appear to be supported by this browser.");
    encodeComponent = function () {
        throw new Error("encodeComponent not supported with this browser");
    };
}

/*todo integrate this code for getXml for Explorer
    var xmlDocument = new ActiveXObject("Microsoft.XMLDOM");
    xmlDocument.loadXML(http.responseText);
*/
/*todo Response.getHtml */

/*** encode */
exports.encode = function (value) {
    if (no(value)) {
        return '';
    } else if (isInstance(value, String)) {
        return encodeComponent(value);
    } else if (isInstance(value, Number)) {
        return encodeComponent(value);
    } else {
        /* works for builtin arrays and objects and user defined
         * lists and dicts */
        return list(value).eachApply(function (key, value) {
            if (!no(value)) {
                return encodeComponent(key) + '=' + encodeComponent(value);
            } else {
                return encodeComponent(key);
            }
        }).join('&');
    }
};


